﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using Yss.KFlow;
using Yss.KFlow.Data;
using Yss.KFlow.Util;
namespace Yss . KFlow . Deal
{
    /// <summary>
    /// 选定图像委托
    /// </summary>
    /// <param name="select"></param>
    public delegate void AfterSelectPic ( Shape select );
    /// <summary>
    /// 命名空间：YssPic
    /// 文件名：YssPic.FormSet
    /// 创建人：winform
    /// 创建时间：2010-5-10
    /// 版本号：0.1
    /// 说明： 画板数据处理类
    /// 修改记录日期       |   修改人      |   版本      | 说明   
    /// -------------------------------------------------------------------
    /// 2010-5-10 | winform | 0.1 | 
    /// </summary> 
    [Serializable]
    class FlowCanvasDeal
    {
        public FlowCanvasDeal ( )
        {


        }
        //public event AfterSelectLine YssSelectLine;
        /// <summary>
        /// 选择图片事件
        /// </summary>
        public event AfterSelectPic YssSelectPic;
        /// <summary>
        /// 显示窗体事件
        /// </summary>
        public event AfterSelectPic YssShowForm;

        object yssTag = null;
        /// <summary>
        /// 自定义对象
        /// </summary>
        public object YssTag
        {
            get { return yssTag; }
            set { yssTag = value; }
        }
        private int arrow = 0;
        /// <summary>
        /// 箭头设置对象
        /// </summary>
        public int Arrow
        {
            get { return arrow; }
            set { arrow = value; }
        }

        //IDrawType drawObj;
        //public IDrawType DrawObj
        //{
        //    get { return drawObj; }
        //    set
        //    {
        //        drawObj = value;
        //        this.YssType = drawObj.YssType;
        //        this.Bitmap = drawObj.Pic;
        //    }
        //}
        /// <summary>
        /// 图片
        /// </summary>
        Bitmap bitmap;

        /// <summary>
        /// 鼠标按下时最靠近点线段
        /// </summary>
        KeyValuePair<Point , Point> kvp = new KeyValuePair<Point , Point> ( );
        /// <summary>
        /// 显示的图片
        /// </summary>
        public Bitmap Bitmap
        {
            get { return bitmap; }
            set { bitmap = value; }
        }
        FlowTypes yssType = FlowTypes . None;
        Dictionary<Point , Line> hashPoint = new Dictionary<Point , Line> ( );
        /// <summary>
        /// 临时线条/选中的线条
        /// </summary>
        Line tmpLine , selectedLine;
        /// <summary>
        /// 选中的线条
        /// </summary>
        public Line SelectedLine
        {
            get { return selectedLine; }
            set
            {
                selectedLine = value;
                //if (YssSelectLine != null)
                //{
                //    YssSelectLine(value);
                //}
            }
        }

        private Line newLine;
        /// <summary>
        /// 新线条
        /// </summary>
        public Line NewLine
        {
            get { return newLine; }
            set { newLine = value; }
        }
        /// <summary>
        /// 图形
        /// </summary>
        Shape tmpPic , selectPic;
        /// <summary>
        /// 选中的图像
        /// </summary>
        public Shape SelectPic
        {
            get { return selectPic; }
            set
            {
                selectPic = value;
                if ( YssSelectPic != null && selectPic != null )
                {
                    YssSelectPic ( value );
                }
            }
        }

        /// <summary>
        /// 线条
        /// </summary>
        List<Line> LLine = new List<Line> ( );

        public List<Line> LLines
        {
            get { return LLine; }
            set { LLine = value; }
        }
        List<Shape> LYssPic = new List<Shape> ( );

        public List<Shape> LPics
        {
            get { return LYssPic; }
            set { LYssPic = value; }
        }
        private Point mouseDownPoint , mouseMovePoint ;//, mouseUpPoint;
        /// <summary>
        /// 鼠标按下/弹起位置的图像
        /// </summary>
        private Shape mousDownPic , mouseUpPic;
        //按下鼠标的按键


        /// <summary>
        /// 自定义的添加图片对象
        /// </summary>
        Shape addYssPic;
        /// <summary>
        /// 添加图片在这里设置
        /// </summary>
        public Shape AddPic
        {
            get { return addYssPic; }
            set { addYssPic = value; }
        }
        Util . Direction dire = Direction . None;
        Size baseSize;
        Point baseLocation;
        public void OnMouseDown ( MouseEventArgs e )
        {
            //按下鼠标左键
            if ( e . Button != MouseButtons . Left )
            {
                return;
            }
            //获取鼠标画布坐标         
            mouseDownPoint = new Point ( e . X , e . Y );

            AddOrDel ( mouseDownPoint );


        }
        public void AddOrDel ( Point p )
        {
            selected ( p );
            if ( SelectPic != null )
            {
                baseSize = SelectPic . Pic . Size;
                baseLocation = SelectPic . LocationP;
            }
            ////获取鼠标是否点击在图片上
            mousDownPic = IsPicContain ( p );
            mouseDownPoint = p;
            dire = GetBorder ( p  );
            if ( dire !=Direction.None )
            {
               
                return;
            }
            if ( selectedLine == null && SelectPic == null && yssType == FlowTypes . Pic )
            {
                AddNewPic ( null );
            }
            else if ( yssType == FlowTypes . Del )
            {
                Del ( );
            }
        }

        public void OnMouseMove ( object sender , MouseEventArgs e )
        {
            mouseMovePoint = new Point ( e . X , e . Y );
            if ( e . Button == MouseButtons . None )
            {
                dire = GetBorder ( new Point ( e . X , e . Y ) );
            }

            switch ( dire )
            {
                case Direction . Up:
                    {
                        Cursor . Current = Cursors . SizeNS;


                        break;
                    }
                case Direction . Left:
                    {
                        Cursor . Current = Cursors . SizeWE;
                        break;
                    }
                case Direction . Down:
                    {
                        Cursor . Current = Cursors . SizeNS;
                        break;

                    }
                case Direction . Right:
                    {
                        Cursor . Current = Cursors . SizeWE;
                        break;
                    }
                default:
                    Cursor . Current = Cursors . Default;
                    break;
            }
            if ( e . Button != MouseButtons . Left )
            {
                return;
            }

            switch ( dire )
            {
                case Direction . Up:
                    {
                        Size s = new Size ( baseSize . Width , baseSize . Height + mouseDownPoint . Y - e . Y );
                        Point tmpP = new Point ( baseLocation . X , baseLocation . Y - ( mouseDownPoint . Y - e . Y ) );
                        if ( s . Height < 20  )
                        {
                            return;
                        }                        
                        SelectPic . SetPicSize ( s );
                        SelectPic . LocationP = new Point ( baseLocation . X , baseLocation . Y - ( mouseDownPoint . Y - e . Y ) );
                        Control c = sender as Control;
                        c . Refresh ( );
                        return;
                    }
                case Direction . Left:
                    {
                        Size s = new Size ( baseSize . Width +mouseDownPoint.X -e.X , baseSize . Height);
                        Point tmpP = new Point ( baseLocation . X -(mouseDownPoint.X -e.X ), baseLocation . Y );
                        if ( s .Width  < 20 )
                        {
                            return;
                        }
                        SelectPic . SetPicSize ( s );
                        SelectPic . LocationP = tmpP;
                        Control c = sender as Control;
                        c . Refresh ( );
                        return;
                        
                    }
                case Direction . Down:
                    {

                        Size s = new Size ( baseSize . Width , baseSize . Height - mouseDownPoint . Y +e . Y );
                        Point tmpP = new Point ( baseLocation . X , baseLocation . Y );
                        if ( s . Height < 20 )
                        {
                            return;
                        }
                        SelectPic . SetPicSize ( s );
                        SelectPic . LocationP = tmpP;
                        Control c = sender as Control;
                        c . Refresh ( );
                        return;

                    }
                case Direction . Right:
                    {

                        Size s = new Size ( baseSize . Width - mouseDownPoint . X + e . X , baseSize . Height );
                        Point tmpP = new Point ( baseLocation . X , baseLocation . Y );
                        if ( s . Width < 20 )
                        {
                            return;
                        }
                        SelectPic . SetPicSize ( s );
                        SelectPic . LocationP = tmpP;
                        Control c = sender as Control;
                        c . Refresh ( );
                        return;
                    }
            }
            if ( yssType == FlowTypes . None
                && selectedLine != null
                && kvp . Key != kvp . Value
                && mouseMovePoint != new Point ( 0 , 0 )
                )
            {
                Control c = sender as Control;
                c . Refresh ( );
                if ( c != null )
                {
                    Graphics g = c . CreateGraphics ( );
                    Point p1 , p2 , p3;
                    g . DrawLine ( new Pen ( Color . LightGray ) , new Point ( 0 , e . Y ) , new Point ( c . Size . Width , e . Y ) );
                    g . DrawLine ( new Pen ( Color . LightGray ) , new Point ( e . X , 0 ) , new Point ( e . X , c . Size . Height ) );
                    int startDistance = ( int ) Math . Sqrt ( ( mouseDownPoint . X - kvp . Key . X ) * ( mouseDownPoint . X - kvp . Key . X ) + ( mouseDownPoint . Y - kvp . Key . Y ) * ( mouseDownPoint . Y - kvp . Key . Y ) );
                    int endDistance = ( int ) Math . Sqrt ( ( mouseDownPoint . X - kvp . Value . X ) * ( mouseDownPoint . X - kvp . Value . X ) + ( mouseDownPoint . Y - kvp . Value . Y ) * ( mouseDownPoint . Y - kvp . Value . Y ) );
                    bool flag = true;
                    int min = Math . Min ( startDistance , endDistance );
                    if ( min == endDistance )
                    {
                        flag = false;
                    }
                    if ( startDistance < 10 && startDistance >= 0 && flag )
                    {
                        IEnumerator<KeyValuePair<Point , Point>> ie = selectedLine . PLine . GetEnumerator ( );
                        Point tmpPP = ie . Current . Key;
                        while ( ie . MoveNext ( ) )
                        {
                            if ( ie . Current . Value == kvp . Key )
                            {
                                tmpPP = ie . Current . Key;
                                break;
                            }
                        }
                        if ( tmpPP == new Point ( 0 , 0 ) )
                        {
                            tmpPP = kvp . Key;
                        }

                        g . DrawLines ( new Pen ( Color . Green , 1 ) , new Point [ ] { tmpPP , new Point ( e . X , e . Y ) , kvp . Value } );
                    }
                    else if ( endDistance < 10 && endDistance >= 0 && !flag )
                    {
                        IEnumerator<KeyValuePair<Point , Point>> ie = selectedLine . PLine . GetEnumerator ( );
                        Point tmpPP = ie . Current . Key;
                        while ( ie . MoveNext ( ) )
                        {
                            if ( ie . Current . Key == kvp . Value )
                            {
                                tmpPP = ie . Current . Value;
                                break;
                            }
                        }
                        if ( tmpPP == new Point ( 0 , 0 ) )
                        {
                            tmpPP = kvp . Value;
                        }
                        g . DrawLines ( new Pen ( Color . Green , 1 ) , new Point [ ] { kvp . Key , new Point ( e . X , e . Y ) , tmpPP } );
                    }
                    else
                    {

                        g . DrawLines ( new Pen ( Color . Green , 1 ) , new Point [ ] { kvp . Key , new Point ( e . X , e . Y ) , kvp . Value } );
                    }
                    mouseMovePoint = new Point ( e . X , e . Y );
                    return;
                }
            }
            else if ( yssType == FlowTypes . None
                && SelectPic != null
                && mouseMovePoint != new Point ( 0 , 0 )
                )
            {
                if ( Math . Sqrt ( ( mouseDownPoint . X - mouseMovePoint . X ) * ( mouseDownPoint . X - mouseMovePoint . X ) + ( mouseMovePoint . Y - mouseDownPoint . Y ) * ( mouseMovePoint . Y - mouseDownPoint . Y ) ) < 4 )
                {
                    return;
                }
           

                Control c = sender as Control;
                c . Refresh ( );
                Graphics g = c . CreateGraphics ( );
                SelectPic . LocationP = new Point ( baseLocation . X + e . X - mouseDownPoint . X , baseLocation . Y + e . Y - mouseDownPoint . Y );
                g . DrawLine ( new Pen ( Color . LightGray ) , new Point ( 0 , SelectPic . GetMiddleP . Y ) , new Point ( c . Size . Width , SelectPic . GetMiddleP . Y ) );
                g . DrawLine ( new Pen ( Color . LightGray ) , new Point ( SelectPic . GetMiddleP . X , 0 ) , new Point ( SelectPic . GetMiddleP . X , c . Size . Height ) );
                
                //g . DrawImage ( SelectPic . Pic , new Point ( e . X , e . Y ) );
                ////为图片添加边框
                //g . DrawRectangle ( new Pen ( Color . Gray ) , e . X , e . Y , SelectPic . Pic . Width , SelectPic . Pic . Height );
            }
            else if ( yssType == FlowTypes . Line
                && SelectPic != null )
            {

            }
            mouseMovePoint = new Point ( e . X , e . Y );
        }
        /// <summary>
        /// 方法：MoveLine;
        /// 参数：Error;
        /// 参数：Error;
        /// 返回类型：
        /// 说明：移动线条
        /// </summary>
        public void MoveLine ( )
        {
            //鼠标释放点在线上
            if ( selectedLine == IsLineContain ( mouseMovePoint ) || kvp . Key == kvp . Value )
            {
                return;
            }
            selectedLine . OldpLine = selectedLine . PLine;
            //鼠标靠近线段的起点,
            int startDistance = ( int ) Math . Sqrt ( ( mouseDownPoint . X - kvp . Key . X ) * ( mouseDownPoint . X - kvp . Key . X ) + ( mouseDownPoint . Y - kvp . Key . Y ) * ( mouseDownPoint . Y - kvp . Key . Y ) );
            int endDistance = ( int ) Math . Sqrt ( ( mouseDownPoint . X - kvp . Value . X ) * ( mouseDownPoint . X - kvp . Value . X ) + ( mouseDownPoint . Y - kvp . Value . Y ) * ( mouseDownPoint . Y - kvp . Value . Y ) );

            if ( startDistance < 30 )
            {
                IEnumerator<KeyValuePair<Point , Point>> ie = selectedLine . PLine . GetEnumerator ( );
                while ( ie . MoveNext ( ) )
                {
                    if ( ie . Current . Value == kvp . Key )
                    {
                        int distance = GetDistance ( ie . Current . Key , mouseMovePoint , kvp . Value );
                        if ( distance < 20 && distance >= 0 )
                        {
                            selectedLine . PLine [ ie . Current . Key ] = kvp . Value;
                            selectedLine . PLine . Remove ( kvp . Key );
                        }
                        else
                        {
                            //修改线段的起点
                            selectedLine . PLine [ ie . Current . Key ] = mouseMovePoint;
                            selectedLine . PLine . Add ( mouseMovePoint , kvp . Value );
                            selectedLine . PLine . Remove ( kvp . Key );
                        }

                        break;


                    }
                }
            }
            //鼠标靠近线段的终点
            else if ( endDistance < 30 )
            {

                IEnumerator<KeyValuePair<Point , Point>> ie = selectedLine . PLine . GetEnumerator ( );
                while ( ie . MoveNext ( ) )
                {
                    //修改线段的终点
                    if ( ie . Current . Key == kvp . Value )
                    {
                        int distance = GetDistance ( ie . Current . Key , mouseMovePoint , selectedLine . PLine [ kvp . Value ] );
                        if ( distance < 20 && distance >= 0 )
                        {
                            selectedLine . PLine [ kvp . Key ] = selectedLine . PLine [ kvp . Value ];
                            selectedLine . PLine . Remove ( kvp . Value );

                        }
                        else
                        {
                            selectedLine . PLine [ kvp . Key ] = mouseMovePoint;
                            selectedLine . PLine . Add ( mouseMovePoint , selectedLine . PLine [ kvp . Value ] );
                            selectedLine . PLine . Remove ( kvp . Value );
                        }
                        break;
                    }
                }
            }
            else
            {

                //添加新的点
                selectedLine . PLine . Add ( mouseMovePoint , selectedLine . PLine [ kvp . Key ] );
                selectedLine . PLine [ kvp . Key ] = mouseMovePoint;
            }



        }

        public void OnMouseUp ( MouseEventArgs e )
        {
            if ( dire != Direction . None )
            {
                dire = Direction . None;
                return;
            }
            
            if ( e . Button != MouseButtons . Left )
            {
                yssType = FlowTypes . None;
                return;
            }
            mouseMovePoint = new Point ( e . X , e . Y );
            mouseUpPic = IsPicContain ( mouseMovePoint );

            //画线
            if ( yssType == FlowTypes . Line )
            {
                if ( mousDownPic == mouseUpPic )
                {
                    return;
                }
                Line yl = AddLine ( );
                if ( yl != null )
                {
                    LLines . Add ( yl );
                }
            }
            //执行拖动操作
            else
            {

                if ( SelectPic != null )
                {
                    //MovePic ( );
                }
                else if ( selectedLine != null )
                {
                    MoveLine ( );
                }

            }

            yssType = FlowTypes . None;


        }
        /// <summary>
        /// 鼠标双击
        /// </summary>
        /// <param name="e"></param>
        public void OnMouseDoubleClick ( MouseEventArgs e )
        {
            Shape yp = IsPicContain ( new Point ( e . X , e . Y ) );
            //string tmp = "";
            if ( yp != null && YssShowForm != null )
            {

                YssShowForm ( yp );
            }

        }
        /// <summary>
        /// 删除选中
        /// </summary>
        public void Del ( )
        {
            //删除选中的图片
            if ( SelectPic != null )
            {
                LPics . Remove ( SelectPic );
                selectPic . Selected = false;
                List<Line> lyLine = new List<Line> ( );
                for ( int i = 0 ; i < LLines . Count ; i++ )
                {
                    if ( LLines [ i ] . StartPic == selectPic || LLines [ i ] . EndPic == selectPic )
                    {
                        lyLine . Add ( LLines [ i ] );
                    }
                }
                for ( int i = 0 ; i < lyLine . Count ; i++ )
                {
                    LLines . Remove ( lyLine [ i ] );
                }
            }
            //删除选中的直线
            if ( selectedLine != null )
            {
                LLines . Remove ( selectedLine );
                selectedLine . Selected = false;
                selectedLine = null;

            }

        }
        public Line TmpLine
        {
            get { return tmpLine; }
            set { tmpLine = value; }
        }
        public Shape TmpPic
        {
            get { return tmpPic; }
            set { tmpPic = value; }
        }
        public FlowTypes FlowType
        {
            get { return yssType; }
            set { yssType = value; }
        }
        /// <summary>
        /// 方法：selected;
        /// 参数：Error;
        /// 参数：Error;
        /// 返回类型：System.Boolean
        /// 说明：
        /// </summary>
        /// <returns></returns>
        public bool selected ( Point p )
        {
            bool isSelect = false;
            //改变线的选中状态
            if ( SelectedLine != null && !SelectedLine . ListP . Contains ( p ) )
            {
                SelectedLine . Selected = false;
                SelectedLine = null;
            }
            //改变图片的选中状态
            if ( SelectPic != null && !( SelectPic . LocationP . X <= p . X
                        && p . X <= SelectPic . LocationP . X + SelectPic . Pic . Width
                        && SelectPic . LocationP . Y <= p . Y
                        && p . Y <= SelectPic . Pic . Height ) )
            {
                SelectPic . Selected = false;
                SelectPic = null;
            }
            //选中图片
            Shape yp = IsPicContain ( p );
            if ( yp != null )
            {
                yp . Selected = true;
                SelectPic = yp;
                if ( selectedLine != null )
                {
                    selectedLine . Selected = false;
                    selectedLine = null;
                }
                isSelect = true;
                return isSelect;
            }
            //选中线条
            TmpLine = IsLineContain ( p );
            if ( TmpLine != null )
            {

                selectedLine = TmpLine;
                TmpLine = null;
                SelectPic = null;
                isSelect = true;
                return isSelect;
            }

            return false;

        }
        ////添加默认图片
        //public bool AddPic()
        //{
        //    return AddPic(null);
        //}

        /// <summary>
        /// 方法：AddPic;
        /// 参数：bit;
        /// 参数：bit;
        /// 返回类型：System.Boolean
        /// 说明：添加自定义图片,添加成功返回true,否则返回false
        /// </summary>
        /// <param name="bit">The bit.自定义的图片</param>
        /// <returns>成功 return true,失败 return false</returns>
        public bool AddNewPic ( Bitmap bit )
        {
            if ( selectedLine != null || SelectPic != null )
            {
                return false;
            }
            if ( IsPicContain ( mouseDownPoint ) != null || IsLineContain ( mouseDownPoint ) != null )
            {
                return false;
            }
            if ( this . Bitmap == null )
            {

                this . Bitmap = new Bitmap ( ( Image ) Resource . test1 , new Size ( 40 , 40 ) );
            }
            //添加突变区域内存在障碍物
            Point [ ] tmpP = new Point [ 4 ];
            tmpP [ 0 ] = mouseDownPoint;
            tmpP [ 1 ] = new Point ( mouseDownPoint . X + this . Bitmap . Width , mouseDownPoint . Y );
            tmpP [ 2 ] = new Point ( mouseDownPoint . X , mouseDownPoint . Y + this . Bitmap . Height );
            tmpP [ 3 ] = new Point ( mouseDownPoint . X + this . Bitmap . Width , mouseDownPoint . Y + this . Bitmap . Height );
            for ( int i = 0 ; i < tmpP . Length ; i++ )
            {
                if ( IsLineContain ( tmpP [ i ] ) != null || IsPicContain ( tmpP [ i ] ) != null )
                {
                    return false;
                }
            }
            //添加图片
            addYssPic = new Shape ( );
            addYssPic . Pic = this . Bitmap;
            addYssPic . LocationP = mouseDownPoint;
            addYssPic . Tag = this . YssTag;
            LPics . Add ( addYssPic );
            addYssPic = null;
            return true;


        }


        /// <summary>
        /// 方法：MovePic;
        /// 参数：Error;
        /// 参数：Error;
        /// 返回类型：
        /// 说明：移动图片
        /// </summary>
        public void MovePic ( )
        {
            if ( SelectPic != null )
            {
                //目标区域没有障碍物则移动图形
                Point [ ] tmpP = new Point [ 4 ];
                tmpP [ 0 ] = mouseMovePoint;
                tmpP [ 1 ] = new Point ( mouseMovePoint . X + this . SelectPic . Pic . Width , mouseMovePoint . Y );
                tmpP [ 2 ] = new Point ( mouseMovePoint . X , mouseMovePoint . Y + this . SelectPic . Pic . Height );
                tmpP [ 3 ] = new Point ( mouseMovePoint . X + this . SelectPic . Pic . Width , mouseMovePoint . Y + this . SelectPic . Pic . Height );
                for ( int i = 0 ; i < tmpP . Length ; i++ )
                {
                    if ( IsPicContain ( tmpP [ i ] ) != null )
                    {
                        return;
                    }
                }
                selectPic . LocationP = mouseMovePoint;

            }
        }
        /// <summary>
        /// 方法：AddLine;
        /// 参数：Error;
        /// 参数：Error;
        /// 返回类型：Yss.KFlow.YssLine
        /// 说明：添加线条
        /// </summary>
        /// <returns></returns>
        public Line AddLine ( )
        {

            if ( mousDownPic != null && mouseUpPic != null )
            {
                //2个图形之间如果已经存在连线则返回
                for ( int i = 0 ; i < LLines . Count ; i++ )
                {
                    if ( LLines [ i ] . StartPic == mousDownPic || LLines [ i ] . StartPic == mouseUpPic )
                    {
                        if ( LLines [ i ] . EndPic == mousDownPic || LLines [ i ] . EndPic == mouseUpPic )
                        {
                            return null;
                        }
                    }
                }
                //添加连线
                Line yl = new Line ( mousDownPic , mouseUpPic );
                if ( PathNode ( yl ) . Length == 0 )
                {
                    return null;
                }
                else
                {
                    yl . Arrow = arrow;
                    return yl;
                }
            }
            return null;
        }
        /// <summary>
        /// 方法：PathNode;
        /// 参数：yLine;
        /// 参数：yLine;
        /// 返回类型：System.Drawing.Point[]
        /// 说明：在图片位置发生变化时,及时修改图片的路径
        /// </summary>
        /// <param name="yLine">The y line.</param>
        /// <returns></returns>
        public Point [ ] PathNode ( Line yLine )
        {

            Point [ ] p = new Point [ 2 ];
            Point p1 = yLine . StartPic . GetMiddleP;
            Point p2 = yLine . EndPic . GetMiddleP;
            Point p3 = p2;
            Point p4 = p1;
            if ( yLine . PLine . Count > 1 )
            {
                IEnumerator<KeyValuePair<Point , Point>> ie = yLine . PLine . GetEnumerator ( );
                int falg = 0;
                while ( ie . MoveNext ( ) )
                {
                    if ( !yLine . PLine . ContainsValue ( ie . Current . Key ) )
                    {
                        p3 = ie . Current . Value;
                        falg++;
                    }
                    if ( !yLine . PLine . ContainsKey ( ie . Current . Value ) )
                    {
                        p4 = ie . Current . Key;
                        falg++;
                    }
                    if ( falg == 2 )
                    {
                        break;
                    }
                }
                if ( p1 . X + yLine . StartPic . Pic . Width / 2 < p3 . X )
                {
                    p1 = yLine . StartPic . ApexPionts [ 4 ];
                }
                else if ( p1 . X > ( p3 . X + yLine . StartPic . Pic . Width / 2 ) )
                {
                    p1 = yLine . StartPic . ApexPionts [ 3 ];
                }
                else if ( p1 . Y + yLine . StartPic . Pic . Height / 2 < p3 . Y )
                {
                    p1 = yLine . StartPic . ApexPionts [ 6 ];
                }
                else
                {
                    p1 = yLine . StartPic . ApexPionts [ 1 ];
                }
                if ( p2 . X + yLine . EndPic . Pic . Width / 2 < p4 . X )
                {
                    p2 = yLine . EndPic . ApexPionts [ 4 ];
                }
                else if ( p1 . X > ( p4 . X + yLine . EndPic . Pic . Width / 2 ) )
                {
                    p2 = yLine . EndPic . ApexPionts [ 3 ];
                }
                else if ( p1 . Y + yLine . EndPic . Pic . Height / 2 < p4 . Y )
                {
                    p2 = yLine . EndPic . ApexPionts [ 6 ];
                }
                else
                {
                    p2 = yLine . EndPic . ApexPionts [ 1 ];
                }
            }
            else
            {
                //从Pic1右边连到Pic2左边
                if ( p1 . X + yLine . StartPic . Pic . Width <= p2 . X )
                {
                    p1 = yLine . StartPic . ApexPionts [ 4 ];
                    p2 = yLine . EndPic . ApexPionts [ 3 ];
                    // direc = Direction.RightToLeft;


                }
                //从Pic1左边连到Pic2右边
                else if ( p2 . X <= p1 . X - yLine . StartPic . Pic . Width )
                {
                    p1 = yLine . StartPic . ApexPionts [ 3 ];
                    p2 = yLine . EndPic . ApexPionts [ 4 ];
                    //  direc = Direction.LeftToRight;

                }
                //从Pic1下边连到Pic2上边
                else if ( p1 . Y + yLine . StartPic . Pic . Height <= p2 . Y )
                {
                    p1 = yLine . StartPic . ApexPionts [ 6 ];
                    p2 = yLine . EndPic . ApexPionts [ 1 ];
                    //  direc = Direction.DownToUp;

                }
                //从Pic1上边连到Pic2下边
                else if ( p2 . Y <= p1 . Y - yLine . StartPic . Pic . Height )
                {
                    p1 = yLine . StartPic . ApexPionts [ 1 ];
                    p2 = yLine . EndPic . ApexPionts [ 6 ];
                    // direc = Direction.UpToDown;
                }
            }

            p [ 0 ] = p1;
            p [ 1 ] = p2;
            //只有一个节点
            if ( yLine . PLine . Count < 2 )
            {
                yLine . PLine . Clear ( );
                yLine . PLine . Add ( p1 , p2 );
            }
            else
            {

                yLine . OldpLine = yLine . PLine;
                IEnumerator<KeyValuePair<Point , Point>> ie = yLine . PLine . GetEnumerator ( );
                KeyValuePair<Point , Point> [ ] kvps = new KeyValuePair<Point , Point> [ 2 ];
                Point pp1 = new Point ( 0 , 0 );
                Point pp2 = new Point ( 0 , 0 );
                while ( ie . MoveNext ( ) )
                {
                    //查找线条的起始点
                    if ( !yLine . PLine . ContainsValue ( ie . Current . Key ) )
                    {
                        pp1 = ie . Current . Key;

                    }
                    //查找线条的终点
                    if ( !yLine . PLine . ContainsKey ( ie . Current . Value ) )
                    {
                        pp2 = ie . Current . Key;
                    }
                    //线条的起始点和终点都找到则终止查找
                    if ( pp1 != new Point ( 0 , 0 ) && pp2 != new Point ( 0 , 0 ) )
                    {
                        break;
                    }
                }
                //修改线条的起点
                if ( !yLine . PLine . ContainsKey ( p1 ) )
                {
                    yLine . PLine . Add ( p1 , yLine . PLine [ pp1 ] );
                    yLine . PLine . Remove ( pp1 );
                }
                //修改线条的终点
                if ( !yLine . PLine . ContainsKey ( p2 ) )
                {
                    yLine . PLine [ pp2 ] = p2;


                }


            }

            return p;





        }

        /// <summary>
        /// 方法：OnPaint;
        /// 参数：e;
        /// 参数：e;
        /// 返回类型：
        /// 说明：重绘方法
        /// </summary>
        /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs"/> instance containing the event data.</param>
        public void OnPaint (Control c, PaintEventArgs e )
        {

            Pen pen1 , pen2 , pen3;
            pen1 = new Pen ( Color . DarkBlue , 1 );
            pen2 = new Pen ( Color . DarkBlue , 1 );
            pen2 . CustomEndCap = new System . Drawing . Drawing2D . AdjustableArrowCap ( 3 , 4 );
            pen3 = new Pen ( Color . DarkBlue , 1 );
            pen3 . CustomEndCap = pen3 . CustomStartCap = new System . Drawing . Drawing2D . AdjustableArrowCap ( 3 , 4 );
            Graphics g = e . Graphics;
            for ( int i = 0 ; i < LLines . Count ; i++ )
            {

                //更新路径
                PathNode ( LLines [ i ] );
                if ( LLine [ i ] . PLine . Count > 1 )
                {
                    GetConnectPoint ( LLine [ i ] . StartPic , new Point ( 0 , 0 ) , LLine [ i ] );
                    GetConnectPoint ( LLine [ i ] . EndPic , new Point ( 0 , 0 ) , LLine [ i ] );
                }
                //获取路径
                Point [ ] p = GetLines ( LLines [ i ] );
                for ( int j = 0 ; j  < p . Length ; j ++ )
                {
                    if ( p [ j ] . X + 10 > c . Size . Width )
                    {
                        c . Size = new Size ( p [ j ] . X+20 , c . Size . Height );
                        c . Refresh ( );
                        return ;
                    }
                    if ( p [ j ] . Y + 10 > c . Size . Height )
                    {
                        c . Size = new Size ( c . Size . Width , p [ j ] . Y +20);
                        c . Refresh ( );
                        return;
                    }
                }
                //Point[] pp = GetLines(LLines[i]);
                //for (int j = 1; j < pp.Length - 1; j++)
                //{
                //    pp[j] = new Point(pp[j].X + 10, pp[j].Y);
                //}
                //g.DrawLines(new Pen(Color.LightGray), pp);

                if ( LLines [ i ] . Arrow == 0 )
                {
                    //画线
                    g . DrawLines ( pen1 , p );
                }
                else if ( LLines [ i ] . Arrow == 1 )
                {
                    g . DrawLines ( pen2 , p );
                }
                else
                {
                    g . DrawLines ( pen3 , p );
                }

            }
            //画选中线
            if ( selectedLine != null )
            {
                Point [ ] p = GetLines ( selectedLine );
                //添加选中方框
                for ( int i = 1 ; i < p . Length - 1 ; i++ )
                {
                    g . DrawRectangle ( new Pen ( Color . DarkBlue ) , p [ i ] . X - 2 , p [ i ] . Y - 2 , 6 , 6 );
                }
                //Point [ ] pp = new Point [ p . Length ];
                //pp [ 0 ] = p [ 0 ];
                //pp [ p . Length - 1 ] = p [ p . Length - 1 ];
                //for ( int i = 1 ; i < p . Length - 1 ; i++ )
                //{
                //    p [ i ] = new Point ( p [ i ] . X + 10 , p [ i ] . Y + 10 );
                //}
                //g . DrawLines ( new Pen ( Color . LightGray ) , pp );
            }
            for ( int i = 0 ; i < LPics . Count ; i++ )
            {
                if ( LPics [ i ] . ApexPionts [ 7 ] . X + 10 > c . Size . Width )
                {
                    c . Size = new Size ( LPics [ i ] . ApexPionts [ 7 ] . X + 20 , c . Size . Height );
                    c . Refresh ( );
                    return;
                }
                if ( LPics [ i ] . ApexPionts [ 7 ] . Y + 10 > c . Size . Height )
                {
                    c . Size = new Size ( c . Size . Width , LPics [ i ] . ApexPionts [ 7 ] . Y + 20 );
                }
                //画图
                g . DrawImage ( LPics [ i ] . Pic , LPics [ i ] . LocationP );
                //为图片添加边框
                g . DrawRectangle ( new Pen ( Color . Gray ) , LPics [ i ] . LocationP . X , LPics [ i ] . LocationP . Y , LPics [ i ] . Pic . Width , LPics [ i ] . Pic . Height );
                //选中图片添加显著标识
                if ( LPics [ i ] . Selected )
                {
                    g . DrawRectangle ( new Pen ( Color . DarkBlue ) , LPics [ i ] . ApexPionts [ 0 ] . X - 1 , LPics [ i ] . ApexPionts [ 0 ] . Y - 1 , 2 , 2 );
                    g . DrawRectangle ( new Pen ( Color . DarkBlue ) , LPics [ i ] . ApexPionts [ 1 ] . X - 1 , LPics [ i ] . ApexPionts [ 1 ] . Y - 1 , 2 , 2 );
                    g . DrawRectangle ( new Pen ( Color . DarkBlue ) , LPics [ i ] . ApexPionts [ 2 ] . X - 1 , LPics [ i ] . ApexPionts [ 2 ] . Y - 1 , 2 , 2 );
                    g . DrawRectangle ( new Pen ( Color . DarkBlue ) , LPics [ i ] . ApexPionts [ 3 ] . X - 1 , LPics [ i ] . ApexPionts [ 3 ] . Y - 1 , 2 , 2 );
                    g . DrawRectangle ( new Pen ( Color . DarkBlue ) , LPics [ i ] . ApexPionts [ 4 ] . X - 1 , LPics [ i ] . ApexPionts [ 4 ] . Y - 1 , 2 , 2 );
                    g . DrawRectangle ( new Pen ( Color . DarkBlue ) , LPics [ i ] . ApexPionts [ 5 ] . X - 1 , LPics [ i ] . ApexPionts [ 5 ] . Y - 1 , 2 , 2 );
                    g . DrawRectangle ( new Pen ( Color . DarkBlue ) , LPics [ i ] . ApexPionts [ 6 ] . X - 1 , LPics [ i ] . ApexPionts [ 6 ] . Y - 1 , 2 , 2 );
                    g . DrawRectangle ( new Pen ( Color . DarkBlue ) , LPics [ i ] . ApexPionts [ 7 ] . X - 1 , LPics [ i ] . ApexPionts [ 7 ] . Y - 1 , 2 , 2 );
                }


            }


        }
        /// <summary>
        /// 方法：IsLineContain;
        /// 参数：p;
        /// 参数：p;
        /// 返回类型：Yss.KFlow.YssLine
        /// 说明：判断是否选中线条
        /// </summary>
        /// <param name="p">The p.</param>
        /// <returns>返回选中的线条</returns>
        public Line IsLineContain ( Point p )
        {
            for ( int i = 0 ; i < LLines . Count ; i++ )
            {
                //获取线的路径               
                IEnumerator<KeyValuePair<Point , Point>> ie = LLines [ i ] . PLine . GetEnumerator ( );
                while ( ie . MoveNext ( ) )
                {
                    //查找P点所在的线段
                    KeyValuePair<Point , Point> kvp = ie . Current;

                    int distance = GetDistance ( kvp . Key , p , kvp . Value );

                    if ( distance < 6 && distance >= 0 )
                    {

                        int max = Math . Max ( kvp . Key . X , kvp . Value . X );
                        int min = Math . Min ( kvp . Key . X , kvp . Value . X );
                        //p点的x坐标在线段2个端点的x坐标之间
                        if ( p . X > min && p . X < max )
                        {
                            if ( p == mouseDownPoint )
                            {
                                //选中此线
                                this . kvp = kvp;
                            }
                            return LLines [ i ];
                        }
                        //p点Y坐标在线段的2个Y坐标之间,认为选中此线
                        max = Math . Max ( kvp . Key . Y , kvp . Value . Y );
                        min = Math . Min ( kvp . Key . Y , kvp . Value . Y );

                        if ( p . Y > min && p . Y < max )
                        {
                            if ( p == mouseDownPoint )
                            {
                                this . kvp = kvp;
                            }
                            return LLines [ i ];
                        }
                    }
                }


            }
            //没有选中线条
            return null;

        }
        /// <summary>
        /// 方法：IsPicContain;
        /// 参数：p;
        /// 参数：p;
        /// 返回类型：Yss.KFlow.YssPic
        /// 说明：判断是否选中图形
        /// </summary>
        /// <param name="p">The p.</param>
        /// <returns>选中的图形</returns>
        public Shape IsPicContain ( Point p )
        {
            for ( int i = 0 ; i < LPics . Count ; i++ )
            {
                //p点在图形LYssPic[i]的区域内
                if ( LPics [ i ] . LocationP . X <= p . X
                    && p . X <= LPics [ i ] . LocationP . X + LPics [ i ] . Pic . Width
                    && LPics [ i ] . LocationP . Y <= p . Y
                    && p . Y <= LPics [ i ] . Pic . Height + LPics [ i ] . LocationP . Y
                    )
                {
                    return LPics [ i ];
                }
            }
            return null;
        }
        /// <summary>
        ///  得到线条经过的拐点
        /// </summary>
        /// <param name="yl">线条</param>
        /// <returns>路径坐标</returns>
        public Point [ ] GetLines ( Line yl )
        {

            while ( true )
            {
                try
                {
                    //定义拐点的个数
                    Point [ ] p = new Point [ yl . PLine . Count + 1 ];

                    IEnumerator<KeyValuePair<Point , Point>> ie = yl . PLine . GetEnumerator ( );
                    //获取线条的起点
                    while ( ie . MoveNext ( ) )
                    {
                        if ( !yl . PLine . ContainsValue ( ie . Current . Key ) )
                        {
                            p [ 0 ] = ie . Current . Key;
                            break;
                        }
                    }
                    int i = 1;
                    while ( true )
                    {
                        //添加路径坐标
                        if ( yl . PLine . ContainsKey ( p [ i - 1 ] ) )
                        {

                            p [ i ] = yl . PLine [ p [ i - 1 ] ];
                            if ( i == p . Length - 1 )
                            {
                                break;
                            }
                            i++;

                        }


                    }
                    //保存当前路径
                    yl . OldpLine = yl . PLine;
                    return p;
                }
                catch
                {
                    //出错还原当前路径
                    yl . PLine = yl . OldpLine;
                }
            }



        }

        /// <summary>
        /// P2 到P1,P3的距离差  
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <returns></returns>
        public int GetDistance ( Point p1 , Point p2 , Point p3 )
        {
            return ( int ) ( Math . Sqrt ( ( p2 . X - p1 . X ) * ( p2 . X - p1 . X ) + ( p2 . Y - p1 . Y ) * ( p2 . Y - p1 . Y ) ) + Math . Sqrt ( ( p3 . X - p2 . X ) * ( p3 . X - p2 . X ) + ( p3 . Y - p2 . Y ) * ( p3 . Y - p2 . Y ) ) - Math . Sqrt ( ( p3 . X - p1 . X ) * ( p3 . X - p1 . X ) + ( p3 . Y - p1 . Y ) * ( p3 . Y - p1 . Y ) ) );
        }
       /// <summary>
       /// 
       /// </summary>
       /// <param name="pic"></param>
       /// <param name="p"></param>
       /// <param name="line"></param>
        public void  GetConnectPoint(Yss.KFlow.Data.Shape pic ,Point p ,Yss.KFlow .Data .Line line)
        {
           
            if ( line . StartPic == pic )
            {

                KeyValuePair<Point , Point> tmpKvp = new KeyValuePair<Point , Point> ( );
                IEnumerator<KeyValuePair<Point , Point>> ie = line . PLine . GetEnumerator ( );
                while (ie.MoveNext ())
                {
                    if ( !line . PLine . ContainsValue ( ie.Current.Key  ) )
                    {
                        p =  ie . Current .Value  ;
                        tmpKvp = ie . Current;
                        break;
                    }
                }
                if ( p . X < pic . LocationP . X )
                {
                    if (! line . PLine . ContainsKey ( pic . ApexPionts [ 3 ] ) )
                    {
                        line . PLine . Add ( pic . ApexPionts [ 3 ] , p );
                        line . PLine . Remove ( tmpKvp . Key );
                    }
                }
                else if ( pic . LocationP . X + pic . Pic . Width < p . X )
                {
                    if ( !line . PLine . ContainsKey ( pic . ApexPionts [ 4 ] ) )
                    {
                        line . PLine . Add ( pic . ApexPionts [ 4 ] , p );
                        line . PLine . Remove ( tmpKvp . Key );
                    }
                }
                else if ( p . Y < pic . LocationP . Y )
                {
                    if ( !line . PLine . ContainsKey ( pic . ApexPionts [ 1 ] ) )
                    {
                        line . PLine . Add ( pic . ApexPionts [ 1 ] , p );
                        line . PLine . Remove ( tmpKvp . Key );
                    }
                }
                else  if ( !line . PLine . ContainsKey ( pic . ApexPionts [ 6 ] ) )
                {
                    line . PLine . Add ( pic . ApexPionts [ 6 ] , p );
                    line . PLine . Remove ( tmpKvp . Key );
                }
            }
            else
            {
                IEnumerator<KeyValuePair<Point , Point>> ie = line . PLine . GetEnumerator ( );
                while ( ie . MoveNext ( ) )
                {
                    if ( !line . PLine . ContainsKey ( ie . Current . Value ) )
                    {
                        p = ie . Current . Key;
                        break;
                    }
                }
                if ( p . X < pic . LocationP . X )
                {
                    line . PLine [ p ] = pic . ApexPionts [ 3 ];
                  
                }
                else if ( pic . LocationP . X + pic . Pic . Width < p . X )
                {
                    line . PLine [ p ] = pic . ApexPionts [ 4 ];
                    //line . PLine . Remove ( tmpKvp . Key );
                }
                else if ( p . Y < pic . LocationP . Y )
                {
                    line . PLine [ p ] = pic . ApexPionts [ 1 ];
                    //line . PLine . Remove ( tmpKvp . Key );
                }
                else
                {
                    line . PLine [ p ] = pic . ApexPionts [ 6 ];
                }
                //line . PLine . Remove ( tmpKvp . Key );
                
            }
           
            
        }


        public void OnKeyDown ( KeyEventArgs e )
        {

            Point p = new Point ( 0 , 0 );
            if ( SelectPic == null )
            {
                return;
            }
            if ( e . KeyCode == Keys . Up )
            {
                p = new Point ( SelectPic . LocationP . X , SelectPic . LocationP . Y - 1 );


            }
            else if ( e . KeyCode == Keys . Down )
            {
                p = new Point ( SelectPic . LocationP . X , SelectPic . LocationP . Y + 1 );
            }
            else if ( e . KeyCode == Keys . Left )
            {
                p = new Point ( SelectPic . LocationP . X - 1 , SelectPic . LocationP . Y );
            }
            else if ( e . KeyCode == Keys . Right )
            {
                p = new Point ( SelectPic . LocationP . X + 1 , SelectPic . LocationP . Y );
            }
            else
            {
                return;
            }

            selectPic . LocationP = p;

        }

        private bool IsContainPic ( Point p )
        {
            Point [ ] tmpP = new Point [ 4 ];
            tmpP [ 0 ] = p;
            tmpP [ 1 ] = new Point ( p . X + this . Bitmap . Width , p . Y );
            tmpP [ 2 ] = new Point ( p . X , p . Y + this . Bitmap . Height );
            tmpP [ 3 ] = new Point ( p . X + this . Bitmap . Width , p . Y + this . Bitmap . Height );
            for ( int i = 0 ; i < tmpP . Length ; i++ )
            {
                if (  IsPicContain ( tmpP [ i ] ) != null )
                {
                    return false;
                }
            }
            return true;
        }


        private Util . Direction GetBorder ( Point p )
        {
            if ( SelectPic == null )
            {
                return Direction . None;
            }
            for ( int i = 0 ; i < LYssPic . Count ; i++ )
            {
                int distance = GetDistance ( SelectPic . LocationP , p , SelectPic . ApexPionts [ 2 ] );
                if ( distance < 2 )
                {
                    return Util . Direction . Up;
                }
                distance = GetDistance ( SelectPic . LocationP , p , SelectPic . ApexPionts [ 5 ] );
                if ( distance < 2 )
                {
                    return Util . Direction . Left;
                }
                distance = GetDistance ( SelectPic . ApexPionts [ 2 ] , p , SelectPic . ApexPionts [ 7 ] );
                if ( distance < 2 )
                {
                    return Util . Direction . Right;
                }
                distance = GetDistance ( SelectPic . ApexPionts [ 5 ] , p , SelectPic . ApexPionts [ 7 ] );
                if ( distance < 2 )
                {
                    return Util . Direction . Down;
                }
            }

            return Direction . None;
        }

    }
}